//
// Created by jinbang.li on 2023/4/6.
//

#include "OpFFDemux.h"
#include "../Log/OpLog.h"
extern "C" {
#include <libavformat/avformat.h>
}
bool OpFFDemux::Open(const char *url) {
    //打开文件流成功 即可获取到文件的总长度，直播点播文件
    int re = avformat_open_input(&ic,url,0,0);
    if (re != 0){
        char  buf[1024] = {0};
        av_strerror(re,buf, sizeof(buf));
        return false;
    }
    re = avformat_find_stream_info(ic,0);
    if (re != 0){
        char  buf[1024] = {0};
        av_strerror(re,buf, sizeof(buf));
        return false;
    }
    this->totolMs = ic->duration/(AV_TIME_BASE/1000);
    OPLOGI("totol ms ==== %d",totolMs);
    GetVideoParam();
    GetAudioParam();
    return true;
}

///音频参数
 OpParameter OpFFDemux::GetAudioParam(){
    if (!ic){
        OPLOGE("GetVpara failed! ic is null");
        return OpParameter();
    }
    //获取了音频流索引
    int re = av_find_best_stream(ic,AVMEDIA_TYPE_AUDIO,-1,-1,0,0);
    if (re < 0){
        OPLOGE("av_find_best_stream failed!");
        return OpParameter();
    }
    audioStream = re;
    OpParameter parameter;
    parameter.parameters = ic->streams[re]->codecpar;
    return parameter;
}
OpData OpFFDemux::Read() {
    if (!ic) return OpData();
    OpData data;
    AVPacket *pkt = av_packet_alloc();
    int  re = av_read_frame(ic,pkt);
    if (re != 0){
        av_packet_free(&pkt);
        return OpData();
    }
    OPLOGI("packet size === %d pts ==== %lld",pkt->size,pkt->pts);
    //data.data = pkt->data;
    data.data = (unsigned char *)pkt;
    data.size = pkt->size;
    if (pkt->stream_index == audioStream){
        data.isAudio = true;
    }else if (pkt->stream_index == videoStream){
        data.isAudio = false;
    } else{
        av_packet_free(&pkt);
        return OpData();
    }
    return data;
}
///视频参数
OpParameter OpFFDemux::GetVideoParam(){
    if (!ic){
        OPLOGE("GetVideoParameter failed,ic is null");
        return OpParameter();
    }
    int re = av_find_best_stream(ic,AVMEDIA_TYPE_VIDEO,-1,-1,0,0);
    if (re < 0){
        OPLOGE("av_find_best_stream failed");
        return OpParameter();
    }
    videoStream = re;
    OpParameter opParameter;
    opParameter.parameters = ic->streams[re]->codecpar;
    return opParameter;
}
OpFFDemux::OpFFDemux() {
    static bool isFirst = true;
    if (isFirst){
        isFirst = false;
        av_register_all();
        avcodec_register_all();
        avformat_network_init();
        OPLOGI("register ffmpeg!");
    }
}